<?php

namespace core;

use PDO;
use PDOException;

abstract class Model
{
    protected static ?PDO $pdo = null; // PHP 8: 可空静态属性

    public function __construct()
    {
        $this->connect();
    }

    /**
     * 建立 PDO 数据库连接
     */
    protected function connect(): void
    {
        if (self::$pdo === null) {
            $dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
            $options = [
                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,   // 抛出异常
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,         // 默认关联数组
                PDO::ATTR_EMULATE_PREPARES   => false,                    // **安全**: 禁用模拟预处理
            ];

            try {
                self::$pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
            } catch (PDOException $e) {
                // 在生产环境中不应暴露详细错误
                throw new PDOException("Database connection failed: " . $e->getMessage());
            }
        }
    }

    /**
     * **安全查询方法**
     * 使用预处理语句防止 SQL 注入
     *
     * @param string $sql SQL 语句 (带 ? 占位符)
     * @param array $params 绑定的参数数组
     * @return \PDOStatement
     */
    protected function query(string $sql, array $params = []): \PDOStatement
    {
        try {
            $stmt = self::$pdo->prepare($sql);
            $stmt->execute($params);
            return $stmt;
        } catch (PDOException $e) {
            // 简单的错误处理，可以根据需要扩展
            throw new \Exception("Query failed: " . $e->getMessage());
        }
    }
}